iT邦幫忙

2025 iThome 鐵人賽

DAY 19
1
DevOps

被稱作Server Restart Engineer的我,也想了解如何實踐可觀測性工程系列 第 19

Day 19 - AWS Kinesis Data Firehose:架構選擇與設計考量(中)

  • 分享至 

  • xImage
  •  

昨天我們探討了在建立可觀測性資料管道時的考量,以及為什麼最後選擇 AWS Kinesis Data Firehose + Lambda 作為我們的即時轉換方案。今天,從OTLP 批次匯出的資料結構開始,讓我們來深入探討 Firehose 細部的設定與設計考量。

OTLP 批次匯出的資料結構

首先,讓我們來看看 OTel Collector 實際匯出的資料長什麼樣子。以下是一個典型的 OTLP metrics 批次匯出範例:

{
  "resourceMetrics": [
    {
      "resource": {
        "attributes": [
          {"key": "service.name", "value": {"stringValue": "api-server"}},
          {"key": "host.name", "value": {"stringValue": "prod-host-1"}}
        ]
      },
      "scopeMetrics": [
        {
          "scope": {"name": "prometheus"},
          "metrics": [
            {
              "name": "http_requests_total",
              "sum": {
                "dataPoints": [
                  {
                    "asInt": "1500",
                    "timeUnixNano": "1633024800000000000",
                    "attributes": [
                      {"key": "method", "value": {"stringValue": "GET"}},
                      {"key": "status", "value": {"stringValue": "200"}}
                    ]
                  },
                  {
                    "asInt": "50",
                    "timeUnixNano": "1633024800000000000",
                    "attributes": [
                      {"key": "method", "value": {"stringValue": "POST"}},
                      {"key": "status", "value": {"stringValue": "500"}}
                    ]
                  }
                ]
              }
            },
            {
              "name": "http_request_duration_seconds",
              "histogram": {
                "dataPoints": [
                  {
                    "count": "1500",
                    "sum": 450.5,
                    "bucketCounts": ["100", "800", "500", "100"],
                    "explicitBounds": [0.1, 0.5, 1.0, 2.0],
                    "timeUnixNano": "1633024800000000000"
                  }
                ]
              }
            }
          ]
        }
      ]
    }
  ]
}

從這個範例可以看到 OTLP 資料的幾個特性:

1. 巢狀的批次結構

OTLP 採用高度巢狀的結構來組織資料:

  • resourceMetrics[]:最外層陣列,包含多個 resource
  • scopeMetrics[]:每個 resource 下可以有多個 scope
  • metrics[]:每個 scope 下包含多個 metric
  • dataPoints[]:每個 metric 下包含多個資料點

一個 OTLP 批次可能包含數百筆遙測資料點,而這些資料點全部被打包在一個 JSON 物件中。

2. Resource 和 Attributes 的層級關係

  • Resource attributes:適用於所有 metrics 的共同屬性(如 service.namehost.name
  • DataPoint attributes:每個資料點特定的屬性(如 HTTP methodstatus

而在查詢時,我們通常需要將這兩者合併成扁平化的欄位。

3. 不同 Metric 類型的資料結構

OTLP 支援多種 metric 類型,每種類型的資料結構不同:

  • Sum/Gauge:簡單的數值型資料點
  • Histogram:包含 buckets 和 bounds
  • Summary:包含 quantiles

這意味著我們需要針對不同類型的 metric 進行不同的轉換邏輯。而除了 Metrics 以外,Traces、Logs 也各有自己的轉換邏輯。

由於不同的 signal 所記錄的資料都各有不同,因此我們也會需要設計多張資料表來放置不同 signal 的紀錄。這時候,我們的 data pipeline 便要有能力去做到根據不同資料 routing 到正確的表格。而 Firehose 則能做到這一點。

Firehose Record Model 的限制

儘管如此,Firehose 在處理資料時仍有一些限制。或許不能說是限制,而是它在處理、識別資料的特性。Firehose 處理資料的核心概念是 record

Record 是什麼?

在 Firehose 中,一個 record 代表一筆將要寫入目的地(如 S3 Table)的資料。當資料寫入 S3 Table 時,每個 record 會對應到 table 中的一筆資料(one row),並且會被分派一個 unique 的 record ID

還記得在上一個段落提到,即便 OTLP 資料中有許多個資料點,只要它在同一批次的資料當中,它就會是同一筆 JSON 檔。

如果我們直接將整個 OTLP 批次當作一筆 record 送進 Firehose,最終在 S3 Table 中只會產生一筆資料,而不是我們預期的數百筆資料點。

假設我們直接將上面的 OTLP JSON 當作一筆 Firehose record:

API Gateway → Firehose (1 record) → S3 Table (1 row)

結果是:

  • Table 中只會有一筆資料
  • 這筆資料包含整個巢狀的 JSON 結構
  • 無法進行有效的查詢和分析

我們需要的是:

API Gateway → Lambda (拆分) → Firehose (N records) → S3 Table (N rows)

這時候,我們就必須識別這包 JSON 檔當中共有幾筆資料,並把它拆成單獨的 request 丟給 Firehose。若我們使用 Firehose 內建的 Lambda,由於它是等到 Firehose 接收資料後,才去做後續的資料處理,所以在這個階段,並沒有辦法把 request 進行拆分。
https://ithelp.ithome.com.tw/upload/images/20251003/201779614unTbnEDWS.png

Firehose 中內建的 Data Transform Lambda,可以直接在 Firehose 裡面進行設定

所以在這裡,我們所採取的架構就會是在 Firehose 前面再加一個 Lambda,去將一個 request 拆分成一筆一筆的紀錄。

結語

今天我們深入探討了為什麼需要在 Firehose 前面加入一個 Lambda 進行資料拆分。核心原因在於:

  1. OTLP 批次結構:一個批次包含多筆巢狀的資料點
  2. Firehose Record Model:一筆 record = Table 中的一筆資料
  3. 資料正規化需求:需要扁平化 resource 和 data point attributes

明天,我們將展示如何實際配置 Firehose 並撰寫 Lambda 轉換函式。

參考資料

OpenTelemetry Protocol Specification - Metrics

AWS Kinesis Data Firehose - Record Format Conversion

AWS Kinesis Data Firehose - Data Transformation

AWS re:Post - Uniqueness checks when streaming data via firehose to s3

OpenTelemetry Collector - Batch Processor


上一篇
Day 18 - AWS Kinesis Data Firehose:架構選擇與設計考量(上)
系列文
被稱作Server Restart Engineer的我,也想了解如何實踐可觀測性工程19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言